﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using JustinAngel.Neurons.Framework;
using JustinAngel.Neurons.Framework.Helpers;
using JustinAngel.Neurons.Framework.Messages;
using JustinAngel.Neurons.Framework.Navigation;
using JustinAngel.Neurons.Pages.Main;
using JustinAngel.Neurons.ServerModel;
using Microsoft.Phone.Shell;
using System.Linq;

namespace JustinAngel.Neurons.Pages.Search
{
    public class SearchViewModel : VViewModelBase
    {
        public SearchViewModel()
        {
            IoC.BuildUp(this);

            MessengerInstance.Register<ApplicationDeactivatedMessage>(this, OnApplicationDecativated);
            CheckForApplicationActivated();
        }

        private string _searchString;
        public string SearchString
        {
            get { return _searchString; }
            set
            {
                _searchString = value;
                RaisePropertyChanged(() => SearchString);
            }
        }

        private string _title;
        public string Title
        {
            get { return _title; }
            set
            {
                _title = value;
                RaisePropertyChanged(() => Title);
            }
        }

        public override void OnDataSet()
        {
            base.OnDataSet();

            Title = "Search " + RealData;
            SearchResults = null;
            SearchString = null;
        }


        private string GetSearchIdentifierFor(string NeuronName)
        {
            if (NeuronName == "TED") return "tedtalksdirector";
            if (NeuronName == "RSA") return "theRSAorg";
            if (NeuronName == "FORA.tv") return "ForaTv";
            return string.Empty;
        }

        public string SearchUri
        {
            get
            {
                return string.Format(
                    "http://pipes.yahoo.com/pipes/pipe.run?_id=d6c05a02fcaf26f791cee802a6026c50&_render=json&neuron={0}&searchString={1}"
                    , GetSearchIdentifierFor(RealData)
                    , SearchString);
            }
        }

        public string RealData { get { return (string)Data; } }

        [Dependency]
        public IWebRequestMaker WebRequestMaker { get; set; }

        [Dependency]
        public IDialogService DialogService { get; set; }

        public ICommand Search
        {
            get
            {
                return new RelayCommand(() =>
                {
                    IsLoading = true;
                    WebRequestMaker.StartWithCredentialsAndTimeout(SearchUri, TimeSpan.FromSeconds(30), 
                        (args) => BeginInvokeOnUIThread(() => OnSearchCompleted(args)), 
                        () => BeginInvokeOnUIThread(OnSearchFailed));
                });
            }
        }

        private void OnSearchFailed()
        {
            DialogService.ShowMessageBox(
                "We couldn't get your search results. We're very sad about it. Either try again or cancel.",
                "DON'T PANIC!",
                MessageBoxButton.OK);

            IsLoading = false;
        }

        private void OnSearchCompleted(Stream obj)
        {
            IsLoading = false;

            searchResultsString = obj.ReadToEnd();

            SetCurrentSearchResults();
        }

        private void SetCurrentSearchResults()
        {
            SearchResultRootRss = Services.DataService.DeserializeStreamToBusinessObject(searchResultsString);
            SearchResults = SearchResultRootRss.Items.Select(rssItem => rssItem.ToVideoItemViewModel).ToList();
            BeginInvokeOnUIThread(() =>
                                      {
                                          RaisePropertyChanged(() => SearchResults);
                                          HasSearchResults = SearchResults.Any();
                                      });
        }

        public RssRootItem SearchResultRootRss { get; set; }

        private List<VideoItemViewModel> _searchResults = null;
        public List<VideoItemViewModel> SearchResults
        {
            get { return _searchResults; }
            set
            {
                _searchResults = value;
            }
        }

        private void CheckForApplicationActivated()
        {
            if (!PhoneApplicationService.Current.State.ContainsKey("searchResultsString"))
                return;

            var data = (string)PhoneApplicationService.Current.State["searchData"];
            if (!string.IsNullOrEmpty(data))
            {
                Data = data;
            }

            data = (string)PhoneApplicationService.Current.State["searchResultsString"];
            if (!string.IsNullOrEmpty(data))
            {
                searchResultsString = data;
                SetCurrentSearchResults();
            }

            data = (string)PhoneApplicationService.Current.State["searchString"];
            if (!string.IsNullOrEmpty(data))
            {
                SearchString = data;
            }


        }

        private void OnApplicationDecativated(ApplicationDeactivatedMessage obj)
        {
            PhoneApplicationService.Current.State["searchResultsString"] = searchResultsString;
            PhoneApplicationService.Current.State["searchString"] = SearchString;
            PhoneApplicationService.Current.State["searchData"] = Data;
        }

        public string searchResultsString;

        private bool _isLoading;
        public bool IsLoading
        {
            get { return _isLoading; }
            set
            {
                _isLoading = value;
                RaisePropertyChangedAndUpdateVSM(() => IsLoading, value);
            }
        }

        public ICommand Cancel
        {
            get { return new RelayCommand(() => MessengerInstance.Send(new NavigateBackMessage())); }
        }

        private bool _hasSearchResults;
        public bool HasSearchResults
        {
            get { return _hasSearchResults; }
            set
            {
                _hasSearchResults = value;
                RaisePropertyChangedAndUpdateVSM(() => HasSearchResults, value);
            }
        }
    }
}

